﻿using Cylong.MongoDB.Extension;
using MongoDB.Driver; 
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Cylong.MongoDB
{
    /// <summary>
    /// mongoDb
    /// </summary>
    public class BaseMongo<TEntity> : IBaseMongo<TEntity> where TEntity : class, IEntity
    {
        protected MongoDbService dbService;
        public BaseMongo()
        {
            dbService = new MongoDbService();
        }

        /// <summary>
        /// 异步新增
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task AddAsync(TEntity entity)
        {
            await dbService.AddAsync(entity);
        }

        /// <summary>
        /// 新增数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity">实体(文档)</param>
        public void Add(TEntity entity)
        {
            AddAsync(entity).Wait();
        }


        /// <summary>
        /// 删除指定ID的数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteById(long id)
        {
            await dbService.DeleteAsync<TEntity>(w => w.PID == id);
        }

        /// <summary>
        /// 更新(先删除后新增)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task Update(TEntity model)
        {
            await dbService.DeleteAsync<TEntity>(w => w.PID == model.PID);
            await dbService.AddAsync(model);
        }

        /// <summary>
        /// 更新指定字段
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<long> Update<T>(Expression<Func<T, bool>> predicate, Expression<Func<T, T>> lambda) where T : class
        {
            return await dbService.UpdateAsync<T>(predicate, lambda);
        }

        /// <summary>
        /// 删除指定ID的数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task Delete(Expression<Func<TEntity, bool>> predicate)
        {
            await dbService.DeleteAsync<TEntity>(predicate);
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> projector = null)
        {
            return await dbService.GetAsync(predicate, projector);
        }



        /// <summary>
        /// 查
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate">查询条件</param>
        /// <param name="projector">查询字段</param>
        /// <returns></returns>
        public async Task<List<TDto>> GetDtoAsync<T, TDto>(Expression<Func<T, bool>> predicate, Expression<Func<T, TDto>> projector) where T : class where TDto : class, new()
        {
            var coll = dbService.GetCollection<T>();

            var project = Builders<T>.Projection.Expression(projector);

            return await coll.Find(predicate).Project(project).ToListAsync();
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TEntity>> projector = null)
        {
            return await dbService.GetListAsync(predicate, projector);
        }


        ///// <summary>
        ///// 分页
        ///// </summary>
        ///// <param name="predicate">过滤条件</param>
        ///// <param name="projector">查询字段</param>
        ///// <param name="desc">顺序、倒叙</param>
        ///// <returns></returns>
        //public async Task<PagedResult<TDto>> GetPageListAsync<TDto>(Expression<Func<TEntity, bool>> predicate,
        //        PagedInput page,
        //        Expression<Func<TEntity, TEntity>> projector = null,
        //        Expression<Func<TEntity, object>> orderby = null,
        //        bool desc = false) where TDto : class, new()
        //{
        //    var data = await dbService.GetPageListAsync(predicate, projector, page.PageIndex, page.PageSize, orderby, desc);

        //    var items = AutoMapperExt.Maps<TDto>(data.Item1);

        //    return new PagedResult<TDto>(data.Item2, 0, page.PageSize, page.PageIndex, items);
        //}

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="IsDelete"></param>
        ///// <returns></returns>
        //public Expression<Func<TEntity, bool>> Where(bool IsDelete = false)
        //{
        //    var where = ExtLinq.True<TEntity>();

        //    //where = where.And(w => w.IsDelete == IsDelete);

        //    return where;
        //}

        
    }
}
